package com.kuaimacode.kframework.code;

import com.kuaimacode.kframework.code.domain.*;
import com.kuaimacode.kframework.code.enums.*;
import com.kuaimacode.kframework.code.services.SysAdminPermissonService;
import com.kuaimacode.kframework.code.services.SysAdminRoleService;
import com.kuaimacode.kframework.code.template.*;
import com.kuaimacode.kframework.code.utils.CodeUtil;
import com.kuaimacode.kframework.code.utils.ResultVoUtil;
import com.kuaimacode.kframework.service.DictService;
import com.kuaimacode.kframework.util.SpringContextUtil;
import com.kuaimacode.kframework.util.ToolUtil;
import com.kuaimacode.kframework.mybatis.mapper.TableMapper;
import com.kuaimacode.kframework.mybatis.models.admin.SysAdminPermission;
import com.kuaimacode.kframework.mybatis.models.sys.Dict;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 * @date 2018/8/14
 */
@Controller
@RequestMapping("/code")
public class GenerateController {
    @Autowired
    private DictService dictService;
    @Autowired
    private TableMapper tableMapper;

    //默认父级菜单ID
    private Long defaultMenuId = 1L;
    //默认超级管理员ID
    private String defaultRoleId = "1";

    @GetMapping(value = {"/index"})
    public String index(Model model){
        model.addAttribute("basic", DefaultValue.getBasic());
        model.addAttribute("fieldList", DefaultValue.fieldList());
        model.addAttribute("fieldType", ToolUtil.enumToMap(FieldType.class));
        model.addAttribute("fieldQuery", ToolUtil.enumToMap(FieldQuery.class));
        model.addAttribute("fieldVerify", ToolUtil.enumToMap(FieldVerify.class));
        model.addAttribute("fieldInputType", ToolUtil.enumToMap(FieldInputType.class));
        // 获取字典列表
        List<Dict> list = dictService.list();
        model.addAttribute("dictList", ToolUtil.objectToMap(list, Dict.class,"name", "title"));
        return "/devtools/code/index";
    }

    @PostMapping("save")
    @ResponseBody
    public ResultVo save(@RequestBody Generate generate){
        Map<String, String> fieldMap = new HashMap<>();
        if(generate.getTemplate().isEntity()){
            fieldMap.put("实体类", EntityTemplate.generate(generate));
        }
        /*if(generate.getTemplate().isValidator()){
            fieldMap.put("验证类", ValidatorTemplate.generate(generate));
        }*/
        if(generate.getTemplate().isRepository()){
            fieldMap.put("数据访问层", RepositoryTemplate.generate(generate));
        }
        if(generate.getTemplate().isService()){
            fieldMap.put("服务层", ServiceTemplate.generate(generate));
            //fieldMap.put("服务实现层", ServiceImplTemplate.generate(generate));
        }
        if(generate.getTemplate().isController()){
            fieldMap.put("控制器", ControllerTemplate.generate(generate));
            //menuRule(generate);
        }
        if(generate.getTemplate().isIndex()){
            fieldMap.put("列表页面", IndexHtmlTemplate.generate(generate));
        }
        if(generate.getTemplate().isAdd()){
            fieldMap.put("添加页面", AddHtmlTemplate.generate(generate));
        }
        if(generate.getTemplate().isDetail()){
            fieldMap.put("详细页面", DetailHtmlTemplate.generate(generate));
        }
        if(generate.getTemplate().isApi()){
            fieldMap.put("API", ApiTemplate.generate(generate));
            fieldMap.put("API服务实现层", ApiServiceTemplate.generate(generate));
        }
        //生成菜单和角色权限
        menuRule(generate);

        return ResultVoUtil.success(fieldMap);
    }

    /**
     * 加载表中字段
     * @param model
     * @return
     */
    @GetMapping("getTable")
    public String getTable(@RequestParam(name = "projectPath", required = false) String projectPath,
                           @RequestParam(name = "packagePath", required = false) String packagePath,
                           @RequestParam(name = "author", required = false) String author,
                           @RequestParam(name = "genTitle", required = false) String genTitle,
                           @RequestParam(name = "genModule", required = false) String genModule,
                           @RequestParam(name = "genPMenu", required = false) Long genPMenu,
                           @RequestParam(name = "tablePrefix", required = false) String tablePrefix,
                           @RequestParam(name = "tableName", required = false) String tableName,
                           @RequestParam(name = "tableEntity", required = false) String tableEntity,
                           Model model){

        Basic basic = new Basic();
        basic.setProjectPath(projectPath);
        basic.setPackagePath(packagePath);
        basic.setAuthor(author);
        basic.setGenTitle(genTitle);
        basic.setGenModule(genModule);
        basic.setGenPMenu(genPMenu);
        basic.setTablePrefix(tablePrefix);
        basic.setTableName(tableName);
        basic.setTableEntity(tableEntity);

        List<Map> lists = tableMapper.listTableColumn(tablePrefix + basic.getTableName());
        List<Field> fields = new ArrayList<>();
        if(lists != null && lists.size() >0){
            for(int i=0;i<lists.size();i++){
                if(lists.get(i) == null) continue;
                fields.add(getField(lists.get(i)));
            }
        }
        model.addAttribute("basic", basic);
        //model.addAttribute("fieldList", DefaultValue.fieldList());
        model.addAttribute("fieldList", fields);
        model.addAttribute("fieldType", ToolUtil.enumToMap(FieldType.class));
        model.addAttribute("fieldQuery", ToolUtil.enumToMap(FieldQuery.class));
        model.addAttribute("fieldVerify", ToolUtil.enumToMap(FieldVerify.class));
        model.addAttribute("fieldInputType", ToolUtil.enumToMap(FieldInputType.class));
        // 获取字典列表
        List<Dict> list = dictService.list();
        model.addAttribute("dictList", ToolUtil.objectToMap(list, Dict.class,"name", "title"));
        return "/devtools/code/index";
    }

    /**
     * 检测是否创建表
     * @param param
     * @param request
     * @return
     */
    @PostMapping("checkTable")
    @ResponseBody
    public ResultVo getTable(@RequestBody Param param, HttpServletRequest request){
        List<Map> lists = tableMapper.listTableColumn(param.getTableName());
        List<Field> fields = new ArrayList<>();
        Boolean flag = false;
        if(lists != null && lists.size() >0){
            flag = true;
            /*for(int i=0;i<lists.size();i++){
                if(lists.get(i) == null) continue;
                fields.add(getField(lists.get(i)));
            }*/
        }
        return ResultVoUtil.success(flag);
    }


    /**
     * 根据数据库字段获取Field
     * @param map
     * @return
     */
    private Field getField(Map map){
        //{"TABLE_CATALOG":"def","IS_NULLABLE":"YES","TABLE_NAME":"user_test","TABLE_SCHEMA":"haokuai","EXTRA":"","COLUMN_NAME":"title","COLUMN_KEY":"","CHARACTER_OCTET_LENGTH":1020,"PRIVILEGES":"select,insert,update,references","COLUMN_COMMENT":"标题","COLLATION_NAME":"utf8mb4_general_ci","COLUMN_TYPE":"varchar(255)","ORDINAL_POSITION":2,"CHARACTER_MAXIMUM_LENGTH":255,"DATA_TYPE":"varchar","CHARACTER_SET_NAME":"utf8mb4"}
        //fields.add(new Field("status", "数据状态", FieldType.Byte.getCode(), 2, "SEARCH_STATUS", 0, true,null));
        String columnName =  (String)map.get("COLUMN_NAME");
        String filedName = CodeUtil.underline2Camel(columnName, false);
        String comment = (String)map.get("COLUMN_COMMENT");
        String dataType = (String)map.get("DATA_TYPE");

        Integer filedType = null;
        Integer inputType = 0;
        String dict = "";
        Integer query = 0;
        Boolean show = false;
        List<Integer> verify = null;

        switch (filedName){
            case "id":
                filedType = FieldType.Long.getCode();
                show = true;
                break;
            case "createAt":
                filedType = FieldType.Date.getCode();
                show = true;
                break;
            case "updateAt":
                filedType = FieldType.Date.getCode();
                show = false;
                break;
            case "createBy":
                filedType = FieldType.Long.getCode();
                show = true;
                break;
            case "updateBy":
                filedType = FieldType.Long.getCode();
                show = true;
                break;
            case "status":
                filedType = FieldType.Integer.getCode();
                show = false;
                break;
            default:
                filedType = CodeUtil.getFieldType(dataType);
                show = false;

        }
        return new Field(filedName, comment, filedType, inputType, dict, query, show,verify);
    }

    /**
     * 自动生成菜单和角色权限
     */
    private void menuRule(Generate generate){
        Basic basic = generate.getBasic();
        Template template = generate.getTemplate();
        SysAdminPermissonService menuService = SpringContextUtil.getBean(SysAdminPermissonService.class);
        SysAdminRoleService roleService = SpringContextUtil.getBean(SysAdminRoleService.class);
        String entity = ToolUtil.lowerFirst(basic.getTableEntity());

        // 生成列表菜单
        if(template.isIndex()){
            String url = "/" + entity + "/index";
            SysAdminPermission menu = new SysAdminPermission();
            menu.setUrl(url);
            menu.setPermissionType(MenuTypeEnum.SUB_LEVEL.getCode());//菜单
            menu.setPermissionName(basic.getGenTitle()+"列表");
            menu.setPercode("system:"+entity+":index");
            menu.setParentPermissionId(defaultMenuId);
            menu.setIsAvailable(true);
            menu.setIcon("fa-cog");
            menu.setSort(0);
            //父菜单ID
            menuService.createPermission(menu);
            Long parentPermissionId = menuService.getLastInsertId();
            // 授权给超级管理员组角色
            String[] param0 = { parentPermissionId+"" };
            roleService.grant(defaultRoleId, param0);

            // 子菜单通用字段
            menu.setParentPermissionId(parentPermissionId);
            menu.setPermissionType(MenuTypeEnum.NOT_MENU.getCode());

            // 生成添加/编辑菜单
            if(template.isAdd()){
                url = "/" + entity + "/add";
                menu.setPermissionName(basic.getGenTitle()+"添加");
                menu.setPercode("system:"+entity+":add");
                menu.setUrl(url);
                menuService.createPermission(menu);
                Long addPermissionId = menuService.getLastInsertId();

                // 授权给超级管理员组角色
                String[] param1 = { addPermissionId+"" };
                roleService.grant(defaultRoleId, param1);

                url = "/" + entity + "/edit";
                menu.setPermissionName(basic.getGenTitle()+"编辑");
                menu.setPercode("system:"+entity+":edit");
                menu.setUrl(url);
                menuService.createPermission(menu);
                Long editPermissionId = menuService.getLastInsertId();

                // 授权给超级管理员组角色
                String[] param2 = { editPermissionId+"" };
                roleService.grant(defaultRoleId, param2);
            }

            // 生成详细菜单
            if(template.isDetail()){
                url = "/" + entity + "/delete";
                menu.setPermissionName(basic.getGenTitle()+"删除");
                menu.setPercode("system:"+entity+":delete");
                menu.setUrl(url);
                menuService.createPermission(menu);
                Long deletePermissionId = menuService.getLastInsertId();

                // 授权给超级管理员组角色
                String[] param3 = { deletePermissionId+"" };
                roleService.grant(defaultRoleId, param3);
            }

        }
    }
}
